package com.dkm.orproject.dkmoa.service.serviceimpl.flow;

import com.dkm.orproject.dkmoa.dao.*;
import com.dkm.orproject.dkmoa.domain.*;
import com.dkm.orproject.dkmoa.service.flow.OaVacateFlowService;
import com.dkm.orproject.utils.utils.IdToobtainUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 *  @ClassName : OaVacateFlowServiceImpl  //类名
 *  @Description : 请假流程实现类  //描述
 *  @Author : 石智诚  //作者
 *  @Date: 2020-11-03 10:12  //时间
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OaVacateFlowServiceImpl  implements OaVacateFlowService {
    /**
     * 请假流程Mapper
     */
    @Resource
    OaVacateFlowMapper mapper;
    /**
     * 通知人员关联Mapper
     */
    @Resource
    OaInformMapper informMapper;
    /**
     * id 工具类
     */
    @Resource
    IdToobtainUtils idToobtainUtils;
    /**
     * 部门
     */
    @Resource
    OaDepartmentMapper departmentMapper;
    /**
     * 流程记录日志
     */
    @Resource
    OaFlowScheduleMapper flowScheduleMapper;
    /**
     * 通知Mapper
     */
    @Resource
    OaMessageMapper messageMapper;
    /**
     * 人员mapper
     *
     */
    @Resource
    OaPersonnelMapper personnelMapper;
    /**起草起点*/
    private  static final Long VACATE_START=773567425932308480L;
    /**部门审核*/
    private  static final Long VACATE_DEPART=773567097832878080L;
    /**行政部管理*/
    private  static final Long VACATE_ADMIN=773567186487881728L;
    /**总经理起点*/
    private  static final Long VACATE_GM=773567327169032192L;
    /**结束*/
    private  static final Long VACATE_END=773567457620275200L;
    /**
     * 根据id 删除请假流程
     * @param pkVacateId 请假流程id
     * @return 成功的数量
     */
    @Override
    public int deleteById(Long pkVacateId) {
        return mapper.deleteById(pkVacateId);
    }

    /**
     * 起草流程
     * @param record 请假流程模型
     * @param  personnel 操作人
     * @return 添加的数量
     */
    @Override
    public int insertSelective(OaVacateFlow record, OaPersonnel personnel) {
        // 创建人
        record.setCreatedBy(personnel.getPersonnelName());
        // 创建定级流程名
        record.setVacateName(personnel.getPersonnelName() + "的请假流程");
        //申请人
        record.setPersonnelId(personnel.getPkPersonnelId());
        // D为部门填写
        record.setIsRevision("D");
        // 进度设置为行政部填写
        record.setVacateSchedule(VACATE_DEPART);

        if (record.getPkVacateId() == null) {
            //生成定级ID
            record.setPkVacateId(idToobtainUtils.getNumberId());

            addFlowSchedule(VACATE_START,record.getPkVacateId(),personnel,"");
            // 删除多余的通知
            messageMapper.deleteByFormId(record.getPkVacateId());
            OaMessage message = new OaMessage();
            // 通知地址
            message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAudit.html?pkVacateId=");
            // 通知id
            message.setPkMessageId(idToobtainUtils.getNumberId());
            addMeassge(message, personnel.getPersonnelName(), record.getPkVacateId(),
                    record.getVacateName(), "2");
            // 查询部具有行政填写的人
            Long personnelId = departmentMapper.selectByPrimaryKey(personnel.getPkDepartmentId()).getPersonnelId();
            noPass(personnelId,message.getPkMessageId());
            return mapper.insertSelective(record);
        } else {
            //流程记录
            addFlowSchedule(VACATE_START,record.getPkVacateId(),personnel,"");
            //删除多余的通知
            messageMapper.deleteByFormId(record.getPkVacateId());
            OaMessage message = new OaMessage();
            //通知地址
            message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAudit.html?pkVacateId=");
            //通知id
            message.setPkMessageId(idToobtainUtils.getNumberId());
            //2为待办
            addMeassge(message, personnel.getPersonnelName(), record.getPkVacateId(),
                    record.getVacateName(), "2");
            //查询部门领导
            Long personnelId = departmentMapper.selectByPrimaryKey(personnel.getPkDepartmentId()).getPersonnelId();
            noPass(personnelId,message.getPkMessageId());
            return mapper.updateById(record);
        }
    }

    /**
     * 部门领导审核(通过的情况下)
     * @param pkVacateId 请假流程模型
     * @param departmentOpinion 部门意见
     * @param personnel 操作人
     * @return 成功的数量
     */
    @Override
    public int departmentPass(Long pkVacateId, OaPersonnel personnel,String departmentOpinion)
    {
        OaVacateFlow flow = mapper.selectById(pkVacateId);
        // R为行政部填写
        flow.setIsRevision("R");
        // 进度设置为行政部填写
        flow.setVacateSchedule(VACATE_ADMIN);
        //设置通过原因
        flow.setDepartmentOpinion(departmentOpinion);
        //执行语句
        int row=mapper.updateById(flow);
        //流程记录
        addFlowSchedule(VACATE_DEPART,pkVacateId,personnel,"");
        //删除多余的通知
        messageMapper.deleteByFormId(pkVacateId);
        OaMessage message = new OaMessage();
        //通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAudit.html?pkVacateId=");
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //2为待办
        addMeassge(message, personnel.getPersonnelName(), flow.getPkVacateId(),
                flow.getVacateName(), "2");
        //查询行政部
        List<Long> list = personnelMapper.selectByHover("VACATE_ADMIN_INFORM");
        findPersons(list, message);
        return row;
    }
    /**
     * 部门领导审核(不通过的情况下)
     * @param pkVacateId 请假流程模型
     * @param personnel 操作人
     * @param  formReason 不通过的原因
     * @return 成功的数量
     */
    @Override
    public int departmentNoPass(Long pkVacateId, OaPersonnel personnel, String formReason) {
        OaVacateFlow oaVacateFlow = mapper.selectById(pkVacateId);
        // S为起草
        oaVacateFlow.setIsRevision("S");
        // 进度设置为行政部填写
        oaVacateFlow.setVacateSchedule(VACATE_START);
        //执行语句
        int row=mapper.updateById(oaVacateFlow);

        //流程记录
        addFlowSchedule(VACATE_DEPART,oaVacateFlow.getPkVacateId(),personnel,formReason);
        //删除多余的通知
        messageMapper.deleteByFormId(oaVacateFlow.getPkVacateId());
        OaMessage message = new OaMessage();
        //通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAddorUpdate.html?pkVacateId=");
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //2为待办
        addMeassge(message, personnel.getPersonnelName(), oaVacateFlow.getPkVacateId(),
                oaVacateFlow.getVacateName(), "2");
        //查询部门领导
        noPass(oaVacateFlow.getPersonnelId(),message.getPkMessageId());

        return row;

    }
    /**
     * 行政部审核(通过的情况下)
     * @param pkVacateId 请假流程Id
     * @param personnelOpinion 人事意见
     * @param personnel 操作人
     * @return 成功的数量
     */
    @Override
    public int adminPass(Long pkVacateId, OaPersonnel personnel,String personnelOpinion ) {
        //流程记录
        OaVacateFlow flow = mapper.selectById(pkVacateId);
        // G为总经理填写
        flow.setIsRevision("G");
        // 进度设置为行政部填写
        flow.setVacateSchedule(VACATE_GM);
        flow.setPersonnelOpinion(personnelOpinion);
        //执行语句
        int row=mapper.updateById(flow);


        addFlowSchedule(VACATE_ADMIN,pkVacateId,personnel,"");
        //删除多余的通知
        messageMapper.deleteByFormId(pkVacateId);
        OaMessage message = new OaMessage();
        //通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAudit.html?pkVacateId=");
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //2为待办
        addMeassge(message, personnel.getPersonnelName(), flow.getPkVacateId(),
                flow.getVacateName(), "2");
        //查询行政部
        List<Long> list = personnelMapper.selectByHover("VACATE_GM_INFORM");
        findPersons(list, message);
        return row;
    }
    /**
     * 行政部审核(不通过的情况下)
     * @param pkVacateId 请假流程Id
     * @param personnel 操作人
     * @param  formReason 不通过的原因
     * @return 成功的数量
     */
    @Override
    public int adminNoPass(Long pkVacateId, OaPersonnel personnel, String formReason) {
        OaVacateFlow oaVacateFlow = mapper.selectById(pkVacateId);
        // S为当事人填写
        oaVacateFlow.setIsRevision("S");
        // 进度设置为行政部填写
        oaVacateFlow.setVacateSchedule(VACATE_START);
        //执行语句
        int row=mapper.updateById(oaVacateFlow);
        //流程记录
        addFlowSchedule(VACATE_ADMIN,oaVacateFlow.getPkVacateId(),personnel,formReason);
        //删除多余的通知
        messageMapper.deleteByFormId(oaVacateFlow.getPkVacateId());
        OaMessage message = new OaMessage();
        //通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAddorUpdate.html?pkVacateId=");

        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //2为待办
        addMeassge(message, personnel.getPersonnelName(), oaVacateFlow.getPkVacateId(),
                oaVacateFlow.getVacateName(), "2");
        //通知申请人
        noPass(oaVacateFlow.getPersonnelId(),message.getPkMessageId());
        return row;
    }
    /**
     * 总经理审核(通过的情况下)
     * @param pkVacateId 请假流程模型
     * @param personnel 操作人
     * @param managerOpinion 总经理通过的意见
     * @return 成功的数量
     */
    @Override
    public int managerPass(Long pkVacateId, OaPersonnel personnel,String managerOpinion) {
        OaVacateFlow oaVacateFlow = mapper.selectById(pkVacateId);
        // E为结束
        oaVacateFlow.setIsRevision("E");
        // 进度设置为行政部填写
        oaVacateFlow.setVacateSchedule(VACATE_END);
        oaVacateFlow.setManagerOpinion(managerOpinion);
        //执行语句
        int row=mapper.updateById(oaVacateFlow);

        //流程记录
        addFlowSchedule(VACATE_GM,oaVacateFlow.getPkVacateId(),personnel,"");
        //删除多余的通知
        messageMapper.deleteByFormId(oaVacateFlow.getPkVacateId());

        OaMessage message = new OaMessage();
        //通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAudit.html?pkVacateId=");
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //2为待办
        addMeassge(message, personnel.getPersonnelName(), oaVacateFlow.getPkVacateId(),
                oaVacateFlow.getVacateName(), "4");
        //完成以后通知申请人
        noPass(oaVacateFlow.getPersonnelId(),message.getPkMessageId());
        return row;
    }
    /**
     * 总经理审核(不通过的情况下)
     * @param pkVacateId 请假流程Id
     * @param personnel 操作人
     * @param  formReason 不通过的原因
     * @return 成功的数量
     */
    @Override
    public int managerNoPass(Long pkVacateId, OaPersonnel personnel, String formReason) {
        OaVacateFlow oaVacateFlow = mapper.selectById(pkVacateId);
        // S为当事人填写
        oaVacateFlow.setIsRevision("S");
        // 进度设置为行政部填写
        oaVacateFlow.setVacateSchedule(VACATE_START);
        //执行语句
        int row=mapper.updateById(oaVacateFlow);
        //流程记录
        addFlowSchedule(VACATE_GM,oaVacateFlow.getPkVacateId(),personnel,formReason);
        //删除多余的通知
        messageMapper.deleteByFormId(oaVacateFlow.getPkVacateId());
        OaMessage message = new OaMessage();
        //通知地址
        message.setMessageUrl("pages/dkmoa/front/flow/oavacate/oaVacateAddorUpdate.html?pkVacateId=");
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //2为待办
        addMeassge(message, personnel.getPersonnelName(), oaVacateFlow.getPkVacateId(),
                oaVacateFlow.getVacateName(), "2");
        //查询部门领导
        noPass(oaVacateFlow.getPersonnelId(),message.getPkMessageId());
        return row;
    }

    /***
     * 根据id 查询
     * @param pkVacateId 请假流程id
     * @return 请假流程模型
     */
    @Override
    public OaVacateFlow selectById(Long pkVacateId) {
        return mapper.selectById(pkVacateId);
    }

    /**
     * 根据id 查询
     * @param record 请假流程模型
     * @return 请假流程模型
     */
    @Override
    public int updateById(OaVacateFlow record) {
        return mapper.updateById(record);
    }

    /**
     * 查询所有并进行分页
     * @param flow 请假流程
     * @param limit 显示数量
     * @param page 页数
     * @param startDate 开始月份
     * @param endDate 结束月份
     * @return 分页的数据
     */
    @Override
    public List<OaVacateFlow> findAll(OaVacateFlow flow, Integer limit, Integer page, String startDate, String endDate) {
        PageHelper.startPage(limit,page);
        return mapper.findAll(flow,startDate,endDate);
    }

    /**
     * 统计数量
     * @param flow 请假流程
     * @param startDate 开始月份
     * @param endDate 结束月份
     * @return 数量
     */
    @Override
    public Long rowCount(OaVacateFlow flow, String startDate, String endDate) {
        return mapper.rowCount(flow,startDate,endDate);
    }

    @Override
    public int deleteAll(List<Long> list) {
        return mapper.deleteAll(list);
    }

    @Override
    public List<OaVacateFlow>  selectAll(List<Long> list) {
        return mapper.selectAll(list);
    }


    /**
     * 添加流程记录
     * @param flowId 起草Id
     * @param gradeId 表单Id
     * @param personnel  流程操作人
     * @param formReason  操作人
     */
    public void addFlowSchedule(Long flowId,Long gradeId, OaPersonnel personnel,String formReason){
        // 流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        // 流程记录ID
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 起草id
        flowSchedule.setFlowId(flowId);
        // 绑定表单
        flowSchedule.setFormId(gradeId);
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 创建人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增薪资定级记录
        flowScheduleMapper.insertSelective(flowSchedule);

    }    /**
     * 增加增加
     * @param message    通知
     * @param createdBy  创建人
     * @param pkGradeId  定级流程ID
     * @param messgeName 流程名
     * @param isRevision 有效性
     */
    public void addMeassge(OaMessage message, String createdBy, Long pkGradeId, String messgeName, String isRevision) {
        //创建人
        message.setCreatedBy(createdBy);
        //流程id
        message.setFormId(pkGradeId);
        // 通知标题
        message.setMessageName(messgeName);
        //状态
        message.setIsRevision(isRevision);
        // 新增通知
        messageMapper.insertSelective(message);
    }

    /**
     * 不通过的情况下或者通知个人
     * @param personnelId 人员idid
     * @param pkMessageId 通知
     */
    public void noPass(Long personnelId, Long pkMessageId) {
        // 关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(personnelId);
        // 通知id
        inform.setMessageId(pkMessageId);
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);
    }

    /**
     * 通知人
     *
     * @param ids     通知人员的集合
     * @param message 通知
     */
    public void findPersons(List<Long> ids, OaMessage message) {
        if (ids.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : ids) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }
    }
}
